home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / Portable Patmos 1.1 / patmos-src / src / tcpglue.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-01-19  |  10.3 KB  |  517 lines  |  [TEXT/R*ch]

  1. /*
  2.  * BSD-style socket emulation library for the Mac
  3.  * Original author: Tom Milligan
  4.  * Current author: Charlie Reiman - creiman@ncsa.uiuc.edu
  5.  *
  6.  * This source file is placed in the public domian.
  7.  * Any resemblance to NCSA Telnet, living or dead, is purely coincidental.
  8.  *
  9.  *      National Center for Supercomputing Applications
  10.  *      152 Computing Applications Building
  11.  *      605 E. Springfield Ave.
  12.  *      Champaign, IL  61820
  13.  */
  14.  
  15. /*
  16.  *    Glue routines to call the MacTCP drivers
  17.  */
  18.  
  19. #ifdef USEDUMP
  20. # pragma load "socket.dump"
  21.  
  22. #else
  23. # include <Memory.h>
  24. # include <Files.h>
  25. # include <Errors.h>
  26.  
  27. # include <s_types.h>
  28. # include <neti_in.h>
  29.  
  30. # include "sock_str.h"
  31.  
  32. # include "sock_int.h"
  33.  
  34. #endif
  35.  
  36. #include <Devices.h>
  37.  
  38. static short driver = 0;
  39.  
  40. /*
  41.  * Hack fix for MacTCP 1.0.X bug
  42.  */
  43.  
  44. pascal char *ReturnA5(void) = {0x2E8D};
  45.  
  46. OSErr xOpenDriver() 
  47.     if (driver == 0) 
  48.     { 
  49.         ParamBlockRec pb; 
  50.         OSErr io; 
  51.         
  52.         pb.ioParam.ioCompletion = 0L; 
  53.         pb.ioParam.ioNamePtr = "\p.IPP"; 
  54.         pb.ioParam.ioPermssn = fsCurPerm; 
  55.         io = PBOpenSync(&pb); 
  56.         if (io != noErr) 
  57.             return(io); 
  58.         driver = pb.ioParam.ioRefNum; 
  59.     }
  60.     return noErr;
  61. }
  62.  
  63.  
  64. /*
  65.  * create a TCP stream
  66.  */
  67. OSErr xTCPCreate(
  68.     int buflen,
  69.     TCPNotifyProc notify,
  70.     TCPiopb *pb)
  71. {    
  72.     pb->ioCRefNum = driver;
  73.     pb->csCode = TCPCreate;
  74.     pb->csParam.create.rcvBuff = (char *)NewPtr(buflen);
  75.     pb->csParam.create.rcvBuffLen = buflen;
  76.     pb->csParam.create.notifyProc = notify;
  77.     return (xPBControlSync(pb));
  78. }
  79.  
  80. /*
  81.  * start listening for a TCP connection
  82.  */
  83. OSErr xTCPPassiveOpen( 
  84.     TCPiopb *pb, 
  85.     short port,
  86.     TCPIOCompletionProc completion)
  87. {
  88.     if (driver == 0)
  89.         return(invalidStreamPtr);
  90.  
  91.     pb->ioCRefNum = driver;
  92.     pb->csCode = TCPPassiveOpen;
  93.     pb->csParam.open.validityFlags = timeoutValue | timeoutAction;
  94.     pb->csParam.open.ulpTimeoutValue = 255 /* seconds */;
  95.     pb->csParam.open.ulpTimeoutAction = 0 /* 1:abort 0:report */;
  96.     pb->csParam.open.commandTimeoutValue = 0 /* infinity */;
  97.     pb->csParam.open.remoteHost = 0;
  98.     pb->csParam.open.remotePort = 0;
  99.     pb->csParam.open.localHost = 0;
  100.     pb->csParam.open.localPort = port;
  101.     pb->csParam.open.dontFrag = 0;
  102.     pb->csParam.open.timeToLive = 0;
  103.     pb->csParam.open.security = 0;
  104.     pb->csParam.open.optionCnt = 0;
  105.     return (xPBControl(pb,completion));
  106. }
  107.  
  108. /*
  109.  * connect to a remote TCP
  110.  */
  111. OSErr xTCPActiveOpen( 
  112.     TCPiopb *pb, 
  113.     short port,
  114.     long rhost,
  115.     short rport,
  116.     TCPIOCompletionProc completion)
  117. {
  118.     if (driver == 0)
  119.         return(invalidStreamPtr);
  120.  
  121.     pb->ioCRefNum = driver;
  122.     pb->csCode = TCPActiveOpen;
  123.     pb->csParam.open.validityFlags = timeoutValue | timeoutAction;
  124.     pb->csParam.open.ulpTimeoutValue = 60 /* seconds */;
  125.     pb->csParam.open.ulpTimeoutAction = 1 /* 1:abort 0:report */;
  126.     pb->csParam.open.commandTimeoutValue = 0;
  127.     pb->csParam.open.remoteHost = rhost;
  128.     pb->csParam.open.remotePort = rport;
  129.     pb->csParam.open.localHost = 0;
  130.     pb->csParam.open.localPort = port;
  131.     pb->csParam.open.dontFrag = 0;
  132.     pb->csParam.open.timeToLive = 0;
  133.     pb->csParam.open.security = 0;
  134.     pb->csParam.open.optionCnt = 0;
  135.     return (xPBControl(pb,completion));
  136. }
  137.  
  138. OSErr xTCPNoCopyRcv( 
  139.     TCPiopb *pb,
  140.     rdsEntry *rds, 
  141.     int rdslen,
  142.     int    timeout,
  143.     TCPIOCompletionProc completion)
  144. {
  145.     
  146.     if (driver == 0)
  147.         return(invalidStreamPtr);
  148.     
  149.     pb->ioCRefNum = driver;
  150.     pb->csCode = TCPNoCopyRcv;
  151.     pb->csParam.receive.commandTimeoutValue = timeout; /* seconds, 0 = blocking */
  152.     pb->csParam.receive.rdsPtr = (Ptr)rds;
  153.     pb->csParam.receive.rdsLength = rdslen;
  154.     return (xPBControl(pb,completion));
  155. }
  156.  
  157. OSErr xTCPBufReturn(TCPiopb *pb,rdsEntry *rds,TCPIOCompletionProc completion)
  158.     {
  159.     pb->ioCRefNum = driver;
  160.     pb->csCode = TCPRcvBfrReturn;
  161.     pb->csParam.receive.rdsPtr = (Ptr)rds;
  162.     
  163.     return (xPBControl(pb,completion));
  164.     }
  165.     
  166. /*
  167.  * send data
  168.  */
  169. OSErr xTCPSend( 
  170.     TCPiopb *pb,
  171.     wdsEntry *wds, 
  172.     Boolean push,
  173.     Boolean urgent,
  174.     TCPIOCompletionProc completion)
  175. {
  176.     if (driver == 0)
  177.         return invalidStreamPtr;
  178.     
  179.     pb->ioCRefNum = driver;
  180.     pb->csCode = TCPSend;
  181.     pb->csParam.send.validityFlags = timeoutValue | timeoutAction;
  182.     pb->csParam.send.ulpTimeoutValue = 60 /* seconds */;
  183.     pb->csParam.send.ulpTimeoutAction = 0 /* 0:abort 1:report */;
  184.     pb->csParam.send.pushFlag = push;
  185.     pb->csParam.send.urgentFlag = urgent;
  186.     pb->csParam.send.wdsPtr = (Ptr)wds;
  187.     return (xPBControl(pb,completion));
  188. }
  189.  
  190.  
  191. /*
  192.  * close a connection
  193.  */
  194. OSErr xTCPClose(TCPiopb *pb,TCPIOCompletionProc completion) 
  195. {
  196.     if (driver == 0)
  197.         return(invalidStreamPtr);
  198.     
  199.     pb->ioCRefNum = driver;
  200.     pb->csCode = TCPClose;
  201.     pb->csParam.close.validityFlags = timeoutValue | timeoutAction;
  202.     pb->csParam.close.ulpTimeoutValue = 60 /* seconds */;
  203.     pb->csParam.close.ulpTimeoutAction = 1 /* 1:abort 0:report */;
  204.     return (xPBControl(pb,completion));
  205. }
  206.  
  207. /*
  208.  * abort a connection
  209.  */
  210. OSErr xTCPAbort(TCPiopb *pb) 
  211. {
  212.     if (driver == 0)
  213.         return(invalidStreamPtr);
  214.     
  215.     pb->ioCRefNum = driver;
  216.     pb->csCode = TCPAbort;
  217.     return (xPBControlSync(pb));
  218. }
  219.  
  220. /*
  221.  * close down a TCP stream (aborting a connection, if necessary)
  222.  */
  223. OSErr xTCPRelease( 
  224.     TCPiopb *pb)
  225. {
  226.     OSErr io;
  227.     
  228.     if (driver == 0)
  229.         return(invalidStreamPtr);
  230.     
  231.     pb->ioCRefNum = driver;
  232.     pb->csCode = TCPRelease;
  233.     io = xPBControlSync(pb);
  234.     if (io == noErr)
  235.         DisposPtr(pb->csParam.create.rcvBuff); /* there is no release pb */
  236.     return(io);
  237. }
  238.  
  239. int
  240. xTCPBytesUnread(SocketPtr sp) 
  241. {
  242.     TCPiopb    *pb;
  243.     OSErr io;
  244.     
  245.     if (!(pb = sock_fetch_pb(sp)))
  246.         return -1;        /* panic */
  247.     
  248.     if (driver == 0)
  249.         return(-1);
  250.     
  251.     pb->ioCRefNum = driver;
  252.     pb->csCode = TCPStatus;
  253.     io = xPBControlSync(pb);
  254.     if (io != noErr)
  255.         return(-1);
  256.     return(pb->csParam.status.amtUnreadData);
  257. }
  258.  
  259. int
  260. xTCPBytesWriteable(SocketPtr sp)
  261.     {
  262.     TCPiopb *pb;
  263.     OSErr    io;
  264.     long    amount;
  265.     
  266.     if (!(pb = sock_fetch_pb(sp)))
  267.         return -1;        /* panic */
  268.     
  269.     if (driver == 0)
  270.         return(-1);
  271.     
  272.     pb->ioCRefNum = driver;
  273.     pb->csCode = TCPStatus;
  274.     io = xPBControlSync(pb);
  275.     if (io != noErr)
  276.         return(-1);
  277.     amount = pb->csParam.status.sendWindow-pb->csParam.status.amtUnackedData;
  278.     if (amount < 0)
  279.         amount = 0;
  280.     return amount;
  281.     }
  282.     
  283. int xTCPWriteBytesLeft(SocketPtr sp)
  284.     {
  285.     TCPiopb *pb;
  286.     OSErr    io;
  287.     
  288.     if (!(pb = sock_fetch_pb(sp)))
  289.         return -1;        /* panic */
  290.     
  291.     if (driver == 0)
  292.         return(-1);
  293.     
  294.     pb->ioCRefNum = driver;
  295.     pb->csCode = TCPStatus;
  296.     io = xPBControlSync(pb);
  297.     if (io != noErr)
  298.         return(-1);
  299.     return (pb->csParam.status.amtUnackedData);
  300.     }
  301.  
  302. int xTCPState(TCPiopb *pb)
  303.     {
  304.     OSErr io;
  305.     
  306.     if (driver == 0)
  307.         return(-1);
  308.     
  309.     pb->ioCRefNum = driver;
  310.     pb->csCode = TCPStatus;
  311.     io = xPBControlSync(pb);
  312.     if (io != noErr)
  313.         return(-1);
  314.     return(pb->csParam.status.connectionState);
  315.     }
  316.  
  317.  
  318. /*
  319.  * create a UDP stream, hook it to a socket.
  320.  */
  321. OSErr xUDPCreate(SocketPtr sp,int buflen,ip_port port)
  322.     {    
  323.     UDPiopb *pb;
  324.     OSErr   io;
  325.     
  326.     if ( !(pb = sock_fetch_pb(sp) ) )
  327.         return -1;
  328.     
  329.     pb->ioCRefNum = driver;
  330.     pb->csCode = UDPCreate;
  331.     pb->csParam.create.rcvBuff = (char *)NewPtr(buflen);
  332.     pb->csParam.create.rcvBuffLen = buflen;
  333.     pb->csParam.create.notifyProc = NULL;
  334.     pb->csParam.create.localPort = port;
  335.     if ( (io = xPBControlSync( (TCPiopb *)pb ) ) != noErr)
  336.         return io;
  337.         
  338.     sp->stream = pb->udpStream;
  339.     sp->sa.sin_port = pb->csParam.create.localPort;
  340.     return noErr;
  341.     }
  342.  
  343. /*
  344.  * ask for incoming data
  345.  */
  346. OSErr xUDPRead(SocketPtr sp,UDPIOCompletionProc completion) 
  347.     {
  348.     UDPiopb *pb;
  349.     
  350.     if ( !(pb = sock_fetch_pb(sp) ))
  351.         return -1;
  352.     
  353.     if (driver == 0)
  354.         return(invalidStreamPtr);
  355.     
  356.     pb->ioCRefNum = driver;
  357.     pb->csCode = UDPRead;
  358.     pb->csParam.receive.timeOut = 0 /* infinity */;
  359.     pb->csParam.receive.secondTimeStamp = 0/* must be zero */;
  360.     return (xPBControl ( (TCPiopb *)pb, (TCPIOCompletionProc)completion ));
  361.     }
  362.  
  363. OSErr xUDPBfrReturn(SocketPtr sp) 
  364.     {
  365.     UDPiopb *pb;
  366.  
  367.     if ( !(pb = sock_fetch_pb(sp) ))
  368.         return -1;
  369.  
  370.     if (driver == 0)
  371.         return(invalidStreamPtr);
  372.     
  373.     pb->ioCRefNum = driver;
  374.     pb->csCode = UDPBfrReturn;
  375.     pb->csParam.receive.rcvBuff = sp->recvBuf;
  376.     sp->recvBuf = 0;
  377.     sp->recvd   = 0;
  378.     return ( xPBControl( (TCPiopb *)pb,(TCPIOCompletionProc)-1 ) );
  379.     }
  380.  
  381. /*
  382.  * send data
  383.  */
  384. OSErr xUDPWrite(SocketPtr sp,ip_addr host,ip_port port,miniwds *wds,
  385.         UDPIOCompletionProc completion) 
  386.     {
  387.     UDPiopb    *pb;
  388.     
  389.     if ( !(pb = sock_fetch_pb(sp) ))
  390.         return -1;
  391.         
  392.     if (driver == 0)
  393.         return(invalidStreamPtr);
  394.     
  395.     pb->ioCRefNum = driver;
  396.     pb->csCode = UDPWrite;
  397.     pb->csParam.send.remoteHost = host;
  398.     pb->csParam.send.remotePort = port;
  399.     pb->csParam.send.wdsPtr = (Ptr)wds;
  400.     pb->csParam.send.checkSum = true;
  401.     pb->csParam.send.sendLength = 0/* must be zero */;
  402.     return (xPBControl( (TCPiopb *)pb, (TCPIOCompletionProc)completion));
  403.     }
  404.  
  405. /*
  406.  * close down a UDP stream (aborting a read, if necessary)
  407.  */
  408. OSErr xUDPRelease(SocketPtr sp) {
  409.     UDPiopb *pb;
  410.     OSErr io;
  411.  
  412.     if ( !(pb = sock_fetch_pb(sp) ))
  413.         return -1;
  414.     
  415.     if (driver == 0)
  416.         return(invalidStreamPtr);
  417.     
  418.     pb->ioCRefNum = driver;
  419.     pb->csCode = UDPRelease;
  420.     io = xPBControlSync( (TCPiopb *)pb );
  421.     if (io == noErr) {
  422.         DisposPtr(pb->csParam.create.rcvBuff);
  423.         }
  424.     return(io);
  425.     }
  426.  
  427. ip_addr xIPAddr(void) 
  428. {
  429.     struct IPParamBlock pbr;
  430.     OSErr io;
  431.     
  432.     pbr.ioCRefNum = driver;
  433.     pbr.csCode = ipctlGetAddr;
  434.     io = xPBControlSync( (TCPiopb *)&pbr );
  435.     if (io != noErr)
  436.         return(0);
  437.     return(pbr.ourAddress);
  438. }
  439.  
  440. long xNetMask() 
  441. {
  442.     struct IPParamBlock pbr;
  443.     OSErr io;
  444.     
  445.     pbr.ioCRefNum = driver;
  446.     pbr.csCode = ipctlGetAddr;
  447.     io = xPBControlSync( (TCPiopb *)&pbr);
  448.     if (io != noErr)
  449.         return(0);
  450.     return(pbr.ourNetMask);
  451. }
  452.  
  453. unsigned short xMaxMTU()
  454. {
  455.     struct UDPiopb pbr;
  456.     OSErr io;
  457.     
  458.     pbr.ioCRefNum = driver;
  459.     pbr.csCode = UDPMaxMTUSize;
  460.     pbr.csParam.mtu.remoteHost = xIPAddr();
  461.     io = xPBControlSync( (TCPiopb *)&pbr );
  462.     if (io != noErr)
  463.         return(0);
  464.     return(pbr.csParam.mtu.mtuSize);
  465. }
  466.  
  467. OSErr xPBControlSync(TCPiopb *pb) 
  468.     (pb)->ioCompletion = 0L; 
  469.     return PBControlSync((ParmBlkPtr)(pb)); 
  470. }
  471.  
  472. #pragma segment SOCK_RESIDENT
  473.  
  474. OSErr xTCPRcv( 
  475.     TCPiopb *pb,
  476.     Ptr buf, 
  477.     int buflen,
  478.     int    timeout,
  479.     TCPIOCompletionProc completion)
  480. {
  481.     
  482.     if (driver == 0)
  483.         return(invalidStreamPtr);
  484.     
  485.     pb->ioCRefNum = driver;
  486.     pb->csCode = TCPRcv;
  487.     pb->csParam.receive.commandTimeoutValue = timeout; /* seconds, 0 = blocking */
  488.     pb->csParam.receive.rcvBuff = buf;
  489.     pb->csParam.receive.rcvBuffLen = buflen;
  490.     return (xPBControl(pb,completion));
  491. }
  492.  
  493.  
  494. OSErr xPBControl(TCPiopb *pb,TCPIOCompletionProc completion) 
  495.     pb->ioNamePtr = ReturnA5();
  496.     
  497.     if (completion == 0L) 
  498.     { 
  499.         (pb)->ioCompletion = 0L; 
  500.         return(PBControlSync((ParmBlkPtr)(pb)));        /* sync */
  501.     } 
  502.     else if (completion == (TCPIOCompletionProc)-1L) 
  503.     { 
  504.         (pb)->ioCompletion = 0L; 
  505.         return(PBControlAsync((ParmBlkPtr)(pb)));        /* async */
  506.     } 
  507.     else 
  508.     {  
  509.         (pb)->ioCompletion = completion; 
  510.         return(PBControlAsync((ParmBlkPtr)(pb)));        /* async */
  511.     } 
  512. }
  513.  
  514.